package com.starsoft.trade.trader;

import java.sql.Timestamp;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.starsoft.frame.util.DateUtil;
import com.starsoft.frame.util.NumberUtil;
import com.starsoft.smdc.bean.SmdcDiv;
import com.starsoft.smdc.bean.SmdcDivId;
import com.starsoft.smdc.bean.SmdcMarketDaily;
import com.starsoft.smdc.bean.SmdcSecurity;
import com.starsoft.smdc.service.MarketDailyService;
import com.starsoft.smdc.service.SecurityService;
import com.starsoft.smdc.util.SecurityType;
import com.starsoft.trade.bean.TradeBill;
import com.starsoft.trade.bean.TradePosition;
import com.starsoft.trade.order.Order;
import com.starsoft.trade.service.AcountStatusService;
import com.starsoft.trade.service.TradeBillService;
import com.starsoft.trade.service.TradeFeeService;
import com.starsoft.trade.util.TradeType;


@Service
public class LocalTrader {
	@Autowired
	MarketDailyService marketDailyService;
	
	@Autowired
	TradeBillService billService;
	
	@Autowired
	TradeFeeService feeService;
	
	@Autowired
	SecurityService securityService;
	
	@Autowired
	AcountStatusService acountStatusService;
	
	int serialnumber=1000;
	
	public List<TradeBill> trade(Integer acountId, Date tradeDate, List<Order> orders){
		List<TradeBill> bills = new ArrayList<TradeBill>();
		for(int i=0;i<orders.size();i++){
			Order order = orders.get(i);
			if(order.getSecNum() == 0){
				continue;
			}
			SmdcSecurity security = securityService.get(order.getSecId());
			SecurityType securityType = SecurityType.get(security);
			TradeType tradeType = null;
			if(securityType == SecurityType.stock){
				if(order.getSecNum()>0) tradeType = TradeType.stockbuy;
				else tradeType = TradeType.stocksell;
			} else if(securityType == SecurityType.fund){
				if(order.getSecNum()>0) tradeType = TradeType.fundbuy;
				else tradeType = TradeType.fundsell;
			} else if(securityType == SecurityType.index){
				if(order.getSecNum()>0) tradeType = TradeType.indexbuy;
				else tradeType = TradeType.indexsell;
			}
			int serialnumberUsed = getSerialnumber();
			Timestamp billTime = getBillTime(tradeDate, i);
			
			TradeBill bill = new TradeBill();
			bill.setAcountId(acountId);
			bill.setBillSerialnumber(serialnumberUsed);
			bill.setBillTime(billTime);
			bill.setSecId(order.getSecId());
			bill.setSecNum(order.getSecNum());
			bill.setBillType(tradeType.name());
			if(order.getPrice()==null){
				SmdcMarketDaily market =marketDailyService.getMarketDaily(order.getSecId(), tradeDate);
				bill.setSecPrice(market.getClosePrice());
			} else {
				bill.setSecPrice(order.getPrice());
			}
			bill.setBillDesc(order.getDesp());
			billService.saveOrUpdate(bill);
			bills.add(bill);
		}
		return bills;
	}
	
	synchronized private int getSerialnumber(){
		++serialnumber;
		if(serialnumber>10000){
			serialnumber=1000;
		}
		return serialnumber;
	}
	
	private Timestamp getBillTime(Date tradeDate, int sno) {
		ZonedDateTime time = ZonedDateTime.now();
		if(time.getHour()>=23){
			time.withHour(22);
		}
		time = time.plusSeconds(sno);
		ZonedDateTime date = tradeDate.toInstant().atZone(ZoneId.systemDefault());
		ZonedDateTime tradeDateTime = date.withHour(time.getHour()).withMinute(time.getMinute()).withSecond(time.getSecond());
		return Timestamp.from(tradeDateTime.toInstant());
	}
	
	public TradeBill trade(Integer acountId, TradePosition pos, SmdcDiv div) {
		SmdcDivId divId = div.getId();
		SmdcSecurity security = securityService.get(divId.getSecId());
		SecurityType securityType = SecurityType.get(security);
		TradeType tradeType = null;
		if(securityType == SecurityType.stock){
			tradeType = TradeType.stockdiv;
		} else if(securityType == SecurityType.fund){
			tradeType = TradeType.funddiv;
		}

		Double billSecNum = pos.getSecNum() * NumberUtil.null2Zero(div.getPerShareDiv()) + pos.getSecNum()
				* NumberUtil.null2Zero(div.getPerShareTrans());
		double billTradeMoney = pos.getSecNum() * NumberUtil.null2Zero(div.getPerCashDiv());
		if (billSecNum == 0 && billTradeMoney == 0) {
			return null;
		}
		
		TradeBill bill = new TradeBill();
		bill.setBillType(tradeType.name());
		bill.setAcountId(acountId);
		bill.setBillTime(DateUtil.toStamp(divId.getDivDate()));
		bill.setSecId(divId.getSecId());
		bill.setSecNum(billSecNum);
		bill.setBillTradeMoney(billTradeMoney);
		feeService.setFee(bill);
		bill.setBillMoney(billTradeMoney -  NumberUtil.null2Zero(bill.getFeeAll()));
		bill.setBillDesc("分红");
		billService.saveOrUpdate(bill);
		return bill;
	}

}
